package com.osdp.gateway.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.osdp.gateway.service.GatewayRouteService;
import com.osdp.gateway.service.IPermissionService;
import com.osdp.gateway.service.IRouteService;
import com.osdp.gateway.util.JwtUtil;
import com.osdp.gateway.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@Slf4j
@RestController
public class RouteController {

    @Autowired(required=false) //启动时，有就注入，没有就不注入
    private IRouteService routeService;

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private GatewayRouteService gatewayRouteService;

    @RequestMapping("/fallback/{service}")
    public Result fallback(@PathVariable("service") String service){
        if(log.isInfoEnabled()){
            log.info("服务名： {"+ service +"}");
        }
        return Result.fail(String.format("微服务【%s】调用失败,请检查服务是否正常启动", service));
    }
    @RequestMapping("/route/query")
    public Result getNewTenantRoutes(@RequestHeader("X-Access-Token") String token){
        String namespace = JwtUtil.getTenantId(token);
        if(StringUtils.isEmpty(namespace))
            return Result.fail("namespace不能为空！");
        String content = routeService.getTenantRouteConfig(namespace);
        return Result.success(content);
    }

    /**
     * 管理员账号下添加路由
     * @param token
     * @param data
     * @return
     */
    @RequestMapping("/route/save")
    public Result saveNewTenantRoutes(@RequestHeader("X-Access-Token") String token, @RequestBody Map<String,Object> data){
        String namespace = JwtUtil.getTenantId(token);
        if(log.isDebugEnabled()){
            log.info("添加路由[namespace:{}，token:{},data:{}]", namespace, token, data);
        }
        if(!permissionService.hasAdminRole(token)){
            return Result.fail("非管理员，无权修改网关路由");
        }
        Object content = data.get("content");
        try{
            routeService.saveRoute(namespace, JSONArray.toJSONString(content));
        }catch (Exception e){
            return Result.fail(e.getMessage());
        }
        return Result.success("路由添加成功");
    }

    @RequestMapping("/route/add")
    public Boolean saveTenantRoutes(@RequestParam("token") String token, @RequestBody Map<String,Object> data){
        String namespace = JwtUtil.getTenantId(token);
        if(log.isDebugEnabled()){
            log.info("添加路由[namespace:{}，token:{},data:{}]", namespace, token, data);
        }
        if(StringUtils.isEmpty(namespace)){
            return false;
        }
        Object content = data.get("content");
        try{
            routeService.saveRoute(namespace, JSONArray.toJSONString(content));
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @RequestMapping("/service/route")
    public Map<String,String> findServiceRoutes(@RequestBody List<String> services){
        return gatewayRouteService.getServicePath(services);
    }
    @RequestMapping("/route/all/get")
    public String getAllRoutes(){
        List<RouteDefinition> routeList = gatewayRouteService.getRouteDefinitions();
        return JSONArray.toJSONString(routeList);
    }

    @RequestMapping("/route/tenant/get")
    public String getTenantRoutes(@RequestParam("token") String token){
        String namespace = JwtUtil.getTenantId(token);
        List<RouteDefinition> routeList = gatewayRouteService.getRouteDefinitions(namespace);
        return JSONArray.toJSONString(routeList);
    }

    @RequestMapping("/route/load/{routeId}")
    public String loadTenantRoute(@PathVariable("routeId") String routeId){
        RouteDefinition route = gatewayRouteService.getRouteDefinition(routeId);
        return JSONArray.toJSONString(route);
    }
    @RequestMapping("/route/remove/{routeId}")
    public Boolean removeTenantRoute(@PathVariable("routeId") String routeId){
        try{
            gatewayRouteService.removeRouteDefinition(routeId);
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }
    @RequestMapping("/route/put")
    public Boolean putTenantRoute(@RequestBody JSONObject obj, @RequestParam("token") String token){
        String namespace = JwtUtil.getTenantId(token);
        RouteDefinition routeDefinition = obj.toJavaObject(RouteDefinition.class);
        try {
            gatewayRouteService.addRouteDefinition(namespace, routeDefinition);
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @RequestMapping("/route/update")
    public Boolean updateTenantRoute(@RequestBody JSONObject obj){
        RouteDefinition routeDefinition = obj.toJavaObject(RouteDefinition.class);
        if(StringUtils.isEmpty(routeDefinition.getId()))
            return false;
        try {
            gatewayRouteService.updateRouteDefinition(routeDefinition);
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }
}
